package com.shihan.utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @Description 操作 Redis 的工具类
 * @Author shihan
 * @Date 2021/1/26 17:28
 **/
public class RedisUtils {

    public static final String IP = "127.0.0.1";

    public static final int PORT = 6379;

    /**
     * 可用连接实例的最大值，默认值为 8；
     * 如果设置为 -1 表示不限制；
     * 如果 pool 已经分配了 maxActive 个实例，此时 pool 的状态为 exhausted（耗尽）；
     */
    public static final int MAX_ACTIVE = 100;

    /**
     * 控制一个 pool 最多有多少个状态为 idle（空闲）的 jedis 实例，默认也是 8；
     */
    public static final int MAX_IDLE = 20;

    /**
     * 等待可用连接的最大时间，单位毫秒，默认 -1 表示永不超时；
     * 如果超过最大等待时间，则抛出 JedisConnectionException；
     */
    public static final int MAX_WAIT = 3000;

    public static final int TIMEOUT = 3000;

    /**
     * 在 borrow 一个 jedis 实例时，是否提前进行 validate 操作；
     * 如果为 true ，则得到的实例都是可用的；
     */
    public static final boolean TEST_ON_BORROW = true;

    /**
     * 在 return 给 pool 时，是否提前进行 validate 操作；
     */
    public static final boolean TEST_ON_RETURN = true;

    public static JedisPool jedisPool;

    /**
     * redis 过期时间，以秒为单位
     * 一小时
     * 一天
     * 一个月
     */
    public static final int EXPR_HOUR = 60 * 60;
    public static final int EXPR_DAY = 60 * 60 * 24;
    public static final int EXPR_MONTH = 60 * 60 * 24 * 30;

    /**
     * 初始化 Redis 连接
     */
    private static void initialPool() {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);

            jedisPool = new JedisPool(config, IP, PORT, TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 在多线程环境，同步初始化
     */
    private static synchronized void poolInit() {
        if (jedisPool == null) {
            initialPool();
        }
    }

    /**
     * 同步获取 jedis 实例
     *
     * @return
     */
    public synchronized static Jedis getJedis() {
        if (jedisPool == null) {
            poolInit();
        }
        Jedis jedis = null;
        try {
            if (jedisPool != null) {
                jedis = jedisPool.getResource();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jedis;
    }

    /**
     * 释放 jedis 资源
     *
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null && jedisPool != null) {
            jedisPool.returnResource(jedis);
        }
    }

    public static Long sadd(String key, String... members) {
        Jedis jedis = null;
        Long res = null;
        try {
            jedis = getJedis();
            res = jedis.sadd(key, members);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;

    }

}
